package com.sghd.fight.module.game.service.skill.effect;

import com.sghd.common.utils.json.JsonUtils;
import com.sghd.fight.module.game.config.ConfigNames;
import com.sghd.fight.module.game.config.SkillConfig;
import com.sghd.fight.module.game.core.model.Unit;
import com.sghd.fight.module.game.service.room.IRoom;
import com.sghd.fight.module.game.service.room.Player;
import com.sghd.fight.module.game.service.skill.ConfigService;
import com.sghd.fight.module.game.service.skill.Context;
import com.sghd.pojo.fight.game.*;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * @author frank
 * @date 2018-11-21 15:10
 * @desc
 **/
@Component
public class NormalEffect implements Effect {

    private Map<Integer, Integer> pvpAttr2LevelUp;
    private Map<Integer, Integer> pvpAttr2LevelDown;

    private Map<Integer, Integer> pveAttr2LevelUp;
    private Map<Integer, Integer> pveAttr2LevelDown;
    @Autowired
    private ConfigService configService;

    @PostConstruct
    void init() {
        configService.addObserver((o, arg) -> {
            initParams();
        });
    }

    private void initParams() {
        String content = configService.getGConfig(ConfigNames.PVP_WHITE_ELEMENT_LEVEL_ATTR_UP);
        pvpAttr2LevelUp = JsonUtils.string2Map(content, Integer.class, Integer.class);
        content = configService.getGConfig(ConfigNames.PVP_WHITE_ELEMENT_LEVEL_ATTR_DOWN);
        pvpAttr2LevelDown = JsonUtils.string2Map(content, Integer.class, Integer.class);

        content = configService.getGConfig(ConfigNames.PVE_WHITE_ELEMENT_LEVEL_ATTR_UP);
        pveAttr2LevelUp = JsonUtils.string2Map(content, Integer.class, Integer.class);
        content = configService.getGConfig(ConfigNames.PVE_WHITE_ELEMENT_LEVEL_ATTR_DOWN);
        pveAttr2LevelDown = JsonUtils.string2Map(content, Integer.class, Integer.class);
    }

    @Override
    public void execute(Context context, IRoom room, Unit owner, Unit target, Map<String, Object> ctx, SkillReport skillReport, TargetReport targetReport, SkillConfig config) {
        //白色普通攻击
        int attack = MapUtils.getInteger(ctx, Effect.LIGHTING);
        int val = (int) (attack * getBet(owner, target));
        val += getIncress(owner, room.getType());//五行伤害增加量
        val -= getDecress(target, room.getType());//五行伤害减少量
        val = fixHp(owner, target, val, room, config);
        context.addValue(target, UnitValue.HP, -val);
        targetReport.addValue(ValueItem.valueOf(UnitValue.HP, -val));
    }

    /**
     * 五行加伤
     * @param unit
     * @param type
     * @return
     */
    private int getIncress(Unit unit, RoomType type) {
        int total = 0;
        if (unit instanceof Player) {
            Map<ChessType, Integer> element2Level = ((Player) unit).getElement2Level();
            //找到最低的五行等级
            int minLevel = element2Level.values().stream().mapToInt(value -> value).summaryStatistics().getMin();
            for (; minLevel > 0; minLevel--) {
                if (type == RoomType.PVP) {
                    total += pvpAttr2LevelUp.get(minLevel) == null ? 0 : pvpAttr2LevelUp.get(minLevel);
                } else {
                    total += pveAttr2LevelUp.get(minLevel) == null ? 0 : pveAttr2LevelUp.get(minLevel);
                }
            }
        }
        return total;
    }

    /**
     * 五行减伤
     * @param unit
     * @param type
     * @return
     */
    private int getDecress(Unit unit, RoomType type) {
        int total = 0;
        if (unit instanceof Player) {
            Map<ChessType, Integer> element2Level = ((Player) unit).getElement2Level();
            //找到最低的五行等级
            int minLevel = element2Level.values().stream().mapToInt(value -> value).summaryStatistics().getMin();
            for (; minLevel > 0; minLevel--) {
                if (type == RoomType.PVP) {
                    total += pvpAttr2LevelDown.get(minLevel) == null ? 0 : pvpAttr2LevelDown.get(minLevel);
                } else {
                    total += pveAttr2LevelDown.get(minLevel) == null ? 0 : pveAttr2LevelDown.get(minLevel);
                }
            }
        }
        return total;
    }

    @Override
    public EffectType getType() {
        return EffectType.SK_NORMAL;
    }
}
